#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

#define THREADS 4

static pthread_mutex_t mtxs[THREADS];
static const char* str = "abcd";

static void* abcd(void* p) {
    int i = (int) p;

    while(1) {
        // require current mtx, un
        pthread_mutex_lock(mtxs + i);
        fputc(str[i], stdout);
        // unlock next mtx
        pthread_mutex_unlock(mtxs + (i + 1) % THREADS);
    }

    pthread_exit(NULL);
}

int main() {
    int i, err;
    pthread_t threads[THREADS];

    // initialize threads
    for(i = 0; i < THREADS; i++) {
        err = pthread_mutex_init(mtxs + i, NULL);
        if(err) {
            fprintf(stderr, "pthread_mutex_init: %s\n", strerror(err));
            exit(1);
        }
        pthread_mutex_lock(mtxs + i);
    }

    for(i = 0; i < THREADS; i++) {
        pthread_create(threads + i, NULL, abcd, i);
    }


    alarm(2);
    pthread_mutex_unlock(mtxs);

    for(i = 0; i < THREADS; i++) {
        pthread_join(threads[i], NULL);
    }

    exit(0);
}